package com.yanqu.road.logic.rank;

import com.yanqu.road.entity.union.UnionBaseInfo;
import com.yanqu.road.logic.pb.RankPb;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.entity.rank.UnionRank;
import com.yanqu.road.logic.sort.UnionRankSort;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.util.LinkedList;
import java.util.Objects;
import java.util.OptionalInt;
import java.util.stream.IntStream;

public class UnionRankListModel {

	private int rankNum = GameConfig.UNION_RANK_DEFAULT_MAX_COUNT;

	private UnionRankSort sorter;

	private LinkedList<UnionRank> rankList;

	private RankProto.UnionRankListMsg.Builder rankListMsg;

	private RandomHelper worshipRandom = new RandomHelper();

	public void setRankNum(int rankNum) {
		this.rankNum = rankNum;
	}

	public RankProto.UnionRankListMsg.Builder getRankListMsg() {
		return rankListMsg;
	}

	public void setRankListMsg(RankProto.UnionRankListMsg.Builder rankListMsg) {
		this.rankListMsg = rankListMsg;
	}

	public LinkedList<UnionRank> getRankList() {
		return rankList;
	}

	public UnionRankListModel() {
		sorter = new UnionRankSort();
		rankList = new LinkedList<>();
		rankListMsg = RankProto.UnionRankListMsg.newBuilder();
	}

	public void initRankList() {
		rankList = new LinkedList<>();
		rankListMsg = RankProto.UnionRankListMsg.newBuilder();
	}

	public void setRankList(LinkedList<UnionRank> unionRankList) {
		synchronized (rankList) {
			rankList = unionRankList;
			initRankPbMessage();
		}
	}

	public void initRankPbMessage() {
		rankListMsg = RankPb.parseUnionRankListMsg(rankList);
	}

	//领取排行奖励一定要用加锁的
	public int getMyRank(String unionUid) {
		synchronized (this) {
			return unlockGetMyRank(unionUid);
		}
	}

	//排行榜排名可以不加锁
	public int unlockGetMyRank(String unionUid) {
		int i = 0;
		for (int k = 0; k < rankList.size(); k++) {
			UnionRank unionRank = rankList.get(k);
			if(Objects.equals(unionRank.getUnionUid(), unionUid)){
				return i + 1;
			}
			i++;
		}
		return -1;
	}

	public UnionRank getUnionRank(String unionUid){
		for(UnionRank unionRank : rankList){
			if(Objects.equals(unionRank.getUnionUid(), unionUid)){
				return unionRank;
			}
		}
		return null;
	}

	public void removeRank(String unionUid) {
		if (StringUtils.isNullOrEmpty(unionUid)) {
			return;
		}
		synchronized (this) {
			rankList.removeIf(m -> Objects.equals(m.getUnionUid(), unionUid));
			initRankPbMessage();
		}
	}

	/**
	 * 添加到排行
	 */
	public UnionRank rankChange(String unionUid, UnionBaseInfo unionBaseInfo) {
		if(StringUtils.isNullOrEmpty(unionUid) || null == unionBaseInfo){
			return null;
		}
		UnionRank rank = null;
		synchronized (this) {
			int size = rankList.size();
			if (null == getUnionRank(unionUid)) {
				if (size < rankNum) {
					rank = initRank(unionUid, unionBaseInfo);
					rankList.add(rank);
				} else if (rankList.getLast().getUnionBaseInfo().getTotalEarnSpeed().compareTo(unionBaseInfo.getTotalEarnSpeed()) < 0) {
					rank = rankList.getLast();
					setUnionRankInfo(rank, unionUid, unionBaseInfo);
				}
			} else {
				for(UnionRank tempRank : rankList){
					if(Objects.equals(tempRank.getUnionUid(), unionUid)){
						tempRank.setUnionBaseInfo(unionBaseInfo);
						rank = tempRank;
					}
				}
			}
			if(null != rank) {//有变更
				rankList.sort(sorter);
				initRankPbMessage();
			}
		}

		return rank;
	}

	public UnionRank getWorshipRankData() {
		if (rankList.size() > 0) {
			int sumValue = 0;
			for (int i = 0; i < rankList.size(); i++) {
				sumValue += (rankNum - i);
			}
			int randomValue = worshipRandom.next(0, sumValue);
			int weight = 0;
			int result = 0;
			for (int i = 0; i < rankList.size(); i++) {
				weight += (rankNum - i);
				if (randomValue <= weight) {
					result = i;
					break;
				}
			}
			return rankList.get(result);
		}
		return null;
	}

	public static UnionRank initRank(String unionUid, UnionBaseInfo unionBaseInfo) {
		UnionRank unionRank = new UnionRank();
		setUnionRankInfo(unionRank, unionUid, unionBaseInfo);
		return unionRank;
	}

	public static UnionRank setUnionRankInfo(UnionRank unionRank, String unionUid, UnionBaseInfo unionBaseInfo) {
		unionRank.setUnionUid(unionUid);
		unionRank.setUnionBaseInfo(unionBaseInfo);
		return unionRank;
	}
}
